#ifndef   _WX_DEBUG_H_
#define   _WX_DEBUG_H_

#include  <assert.h>
#include  <limits.h>            /*  for CHAR_BIT used below */
#include  "wx/wxchar.h"         /*  for __TFILE__ and wxChar */

#ifdef _DEBUG
#ifndef __WXDEBUG__
#define __WXDEBUG__
#endif /*  !__WXDEBUG__ */
#endif /*  _DEBUG */

#ifdef NDEBUG
#undef __WXDEBUG__
#undef WXDEBUG
#endif /*  NDEBUG */



#ifndef __WXFUNCTION__
#if defined(__DMC__)

#define __WXFUNCTION__ (NULL)
#elif defined(__GNUC__) || \
(defined(_MSC_VER) && _MSC_VER >= 1300) || \
defined(__FUNCTION__)
#define __WXFUNCTION__ __FUNCTION__
#else
/* still define __WXFUNCTION__ to avoid #ifdefs elsewhere */
#define __WXFUNCTION__ (NULL)
#endif
#endif /* __WXFUNCTION__ already defined */

/*  ---------------------------------------------------------------------------- */
/*  Debugging macros */
/*  */
/*  All debugging macros rely on ASSERT() which in turn calls the user-defined */
/*  OnAssert() function. To keep things simple, it's called even when the */
/*  expression is true (i.e. everything is ok) and by default does nothing: just */
/*  returns the same value back. But if you redefine it to do something more sexy */
/*  (popping up a message box in your favourite GUI, sending you e-mail or */
/*  whatever) it will affect all ASSERTs, FAILs and CHECKs in your code. */
/*  */
/*  Warning: if you don't like advice on programming style, don't read */
/*  further! ;-) */
/*  */
/*  Extensive use of these macros is recommended! Remember that ASSERTs are */
/*  disabled in final build (without __WXDEBUG__ defined), so they add strictly */
/*  nothing to your program's code. On the other hand, CHECK macros do stay */
/*  even in release builds, but in general are not much of a burden, while */
/*  a judicious use of them might increase your program's stability. */
/*  ---------------------------------------------------------------------------- */

/*  Macros which are completely disabled in 'release' mode */
/*  */
/*  NB: these functions are implemented in src/common/appcmn.cpp */
#if defined(__cplusplus) && defined(__WXDEBUG__)
/*
  This function is called whenever one of debugging macros fails (i.e.
  condition is false in an assertion). To customize its behaviour, override
  wxApp::OnAssert().

  Parameters:
     szFile and nLine - file name and line number of the ASSERT
     szFunc           - function name of the ASSERT, may be NULL (NB: ASCII)
     szCond           - text form of the condition which failed
     szMsg            - optional message explaining the reason
*/
extern void wxOnAssert( const wxChar *szFile,
    int nLine,
    const char *szFunc,
    const wxChar *szCond,
    const wxChar *szMsg = NULL );

/*  call this function to break into the debugger unconditionally (assuming */
/*  the program is running under debugger, of course) */
extern void wxTrap();

/*  generic assert macro */
#define wxASSERT(cond) wxASSERT_MSG(cond, NULL)


/*  assert with additional message explaining its cause */

/*  compilers can give a warning (such as "possible unwanted ;") when using */
/*  the default definition of wxASSERT_MSG so we provide an alternative */
#if defined(__MWERKS__)
#define wxASSERT_MSG(cond, msg)                                           \
  if ( cond )                                                             \
  {}                                                                      \
  else                                                                    \
    wxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, wxT(#cond), msg)
#else
#define wxASSERT_MSG(cond, msg)                                           \
  if ( cond )                                                             \
    ;                                                                   \
  else                                                                    \
    wxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, wxT(#cond), msg)
#endif

/*  special form of assert: always triggers it (in debug mode) */
#define wxFAIL wxFAIL_MSG(NULL)

/*  FAIL with some message */
#define wxFAIL_MSG(msg) wxFAIL_COND_MSG("wxAssertFailure", msg)

/*  FAIL with some message and a condition */
#define wxFAIL_COND_MSG(cond, msg)                                          \
  wxOnAssert(__TFILE__, __LINE__,  __WXFUNCTION__, wxT(cond), msg)

/*  An assert helper used to avoid warning when testing constant expressions, */
/*  i.e. wxASSERT( sizeof(int) == 4 ) can generate a compiler warning about */
/*  expression being always true, but not using */
/*  wxASSERT( wxAssertIsEqual(sizeof(int), 4) ) */
/*  */
/*  NB: this is made obsolete by wxCOMPILE_TIME_ASSERT() and should no */
/*      longer be used. */
extern bool wxAssertIsEqual( int x, int y );
#else
#define wxTrap()

/*  nothing to do in release mode (hopefully at this moment there are */
/*  no more bugs ;-) */
#define wxASSERT(cond)
#define wxASSERT_MSG(cond, msg)
#define wxFAIL
#define wxFAIL_MSG(msg)
#define wxFAIL_COND_MSG(cond, msg)
#endif  /* __WXDEBUG__ */

#ifdef __cplusplus
/*  Use of wxFalse instead of false suppresses compiler warnings about testing */
/*  constant expression */
extern const bool wxFalse;
#endif

#define wxAssertFailure wxFalse

#define wxCHECK(cond, rc)            wxCHECK_MSG(cond, rc, NULL)
#define wxCHECK_MSG(cond, rc, msg)   wxCHECK2_MSG(cond, return rc, msg)
#define wxCHECK2(cond, op)           wxCHECK2_MSG(cond, op, NULL)

#ifdef __GNUC__
#define wxFORCE_SEMICOLON typedef int wxDummyCheckInt
#else
#define wxFORCE_SEMICOLON struct wxDummyCheckStruct
#endif
/* see comment near the definition of wxASSERT_MSG for the # if/else reason */
#define wxCHECK2_MSG(cond, op, msg)                                       \
  if ( cond )                                                           \
  {}                                                                    \
  else                                                                  \
  {                                                                     \
    wxFAIL_COND_MSG(#cond, msg);                                      \
    op;                                                               \
  }                                                                     \
  struct wxDummyCheckStruct /* just to force a semicolon */


#define wxCHECK_RET(cond, msg)       wxCHECK2_MSG(cond, return, msg)
#define wxMAKE_UNIQUE_ASSERT_NAME           wxMAKE_UNIQUE_NAME(wxAssert_)

#if defined(__WATCOMC__) && defined(__cplusplus)
/* avoid "unused symbol" warning */
#define wxCOMPILE_TIME_ASSERT(expr, msg) \
  class wxMAKE_UNIQUE_ASSERT_NAME { \
    unsigned int msg: expr; \
      wxMAKE_UNIQUE_ASSERT_NAME() { } \
  }
#else
#define wxCOMPILE_TIME_ASSERT(expr, msg) \
  struct wxMAKE_UNIQUE_ASSERT_NAME { unsigned int msg: expr; }
#endif

#define wxMAKE_UNIQUE_ASSERT_NAME2(text) wxCONCAT(wxAssert_, text)

#define wxCOMPILE_TIME_ASSERT2(expr, msg, text) \
  struct wxMAKE_UNIQUE_ASSERT_NAME2(text) { unsigned int msg: expr; }

#define wxMAKE_BITSIZE_MSG(type, size) type ## SmallerThan ## size ## Bits

#define wxASSERT_MIN_BITSIZE(type, size) \
  wxCOMPILE_TIME_ASSERT(sizeof(type) * CHAR_BIT >= size, \
                        wxMAKE_BITSIZE_MSG(type, size))

#ifdef __cplusplus
#if defined(__WXMAC__) || defined(__WIN32__)
extern bool wxIsDebuggerRunning();
#else /*  !Mac */
inline bool wxIsDebuggerRunning() { return false; }
#endif /*  Mac/!Mac */
#endif /* __cplusplus */

#endif  /*  _WX_DEBUG_H_ */
